#pragma once

#include <functional>
#include <list>

class TestStub
{
public:
    virtual const char* name() = 0;
    virtual bool run() = 0;
};


typedef  std::function<TestStub*(void)> TestFactory;

void testAddTest(TestFactory factory);


class TestAdd
{
public:
    TestAdd(TestFactory factory)
    {
        testAddTest(factory);
    }
};

#if 1
#define TEST_CLASS(classname_)                                      \
TestStub* classname_##factory();                                    \
TestAdd classname_##add(classname_##factory); \
class classname_ : public TestStub {                                \
public:                                                             \
    classname_(){}                                                  \
    const char* name(){return #classname_;}
#else
#define TEST_CLASS(classname_)                                      \
class classname_ : public TestStub {                                \
public:                                                             \
    const char* name(){return #classname_;}
#endif

#if 1
#define TEST_CLASS_END(classname_) \
};\
TestStub* classname_##factory(){   \
    return new classname_();\
}
#else
#define TEST_CLASS_END };
#endif

#if 1
#define TEST_CLASS_WRAPPER(fun_name_p_) \
    TEST_CLASS(fun_name_p_##wrapper) bool run(){return fun_name_p_();} \
    TEST_CLASS_END(fun_name_p_##wrapper)
#else
#define TEST_CLASS_WRAPPER
#endif